1   /*
2    * Copyright (C) 2009 The Guava Authors
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  package java.util.concurrent;
18  
19  import java.util.AbstractMap;
20  import java.util.Collections;
21  import java.util.Enumeration;
22  import java.util.HashMap;
23  import java.util.Map;
24  import java.util.Set;
25  
26  /**
27   * Minimal emulation of {@link java.util.concurrent.ConcurrentHashMap}.
28   * Note that javascript intepreter is <a
29   * href="http://code.google.com/docreader/#p=google-web-toolkit-doc-1-5&t=DevGuideJavaCompatibility">
30   * single-threaded</a>, it is essentially a {@link java.util.HashMap},
31   * implementing the new methods introduced by {@link ConcurrentMap}.
32   *
33   * @author Hayward Chan
34   */
35  public class ConcurrentHashMap<K, V>
36      extends AbstractMap<K, V> implements ConcurrentMap<K, V> {
37  
38    private final Map<K, V> backingMap;
39  
40    public ConcurrentHashMap() {
41      this.backingMap = new HashMap<K, V>();
42    }
43  
44    public ConcurrentHashMap(int initialCapacity) {
45      this.backingMap = new HashMap<K, V>(initialCapacity);
46    }
47  
48    public ConcurrentHashMap(int initialCapacity, float loadFactor) {
49      this.backingMap = new HashMap<K, V>(initialCapacity, loadFactor);
50    }
51  
52    public ConcurrentHashMap(Map<? extends K, ? extends V> t) {
53      this.backingMap = new HashMap<K, V>(t);
54    }
55  
56    public V putIfAbsent(K key, V value) {
57      if (!containsKey(key)) {
58        return put(key, value);
59      } else {
60        return get(key);
61      }
62    }
63  
64    public boolean remove(Object key, Object value) {
65      if (containsKey(key) && get(key).equals(value)) {
66        remove(key);
67        return true;
68      } else {
69        return false;
70      }
71    }
72  
73    public boolean replace(K key, V oldValue, V newValue) {
74      if (oldValue == null || newValue == null) {
75        throw new NullPointerException();
76      } else if (containsKey(key) && get(key).equals(oldValue)) {
77        put(key, newValue);
78        return true;
79      } else {
80        return false;
81      }
82    }
83  
84    public V replace(K key, V value) {
85      if (value == null) {
86        throw new NullPointerException();
87      } else if (containsKey(key)) {
88        return put(key, value);
89      } else {
90        return null;
91      }
92    }
93  
94    @Override public boolean containsKey(Object key) {
95      if (key == null) {
96        throw new NullPointerException();
97      }
98      return backingMap.containsKey(key);
99    }
100 
101   @Override public V get(Object key) {
102     if (key == null) {
103       throw new NullPointerException();
104     }
105     return backingMap.get(key);
106   }
107 
108   @Override public V put(K key, V value) {
109     if (key == null || value == null) {
110       throw new NullPointerException();
111     }
112     return backingMap.put(key, value);
113   }
114 
115   @Override public boolean containsValue(Object value) {
116     if (value == null) {
117       throw new NullPointerException();
118     }
119     return backingMap.containsValue(value);
120   }
121 
122   @Override public V remove(Object key) {
123     if (key == null) {
124       throw new NullPointerException();
125     }
126     return backingMap.remove(key);
127   }
128 
129   @Override public Set<Entry<K, V>> entrySet() {
130     return backingMap.entrySet();
131   }
132 
133   public boolean contains(Object value) {
134     return containsValue(value);
135   }
136 
137   public Enumeration<V> elements() {
138     return Collections.enumeration(values());
139   }
140 
141   public Enumeration<K> keys() {
142     return Collections.enumeration(keySet());
143   }
144 }